﻿using Microsoft.EntityFrameworkCore;

namespace Devonline.AspNetCore;

/// <summary>
/// 业务数据附件类服务
/// 一个业务数据中仅有一个类型为: TAttachment 的业务数据的附件集合, 根据 BusinessType 字段区分用途
/// </summary>
/// <typeparam name="TDbContext">数据库上下文</typeparam>
/// <typeparam name="TEntitySet">业务数据类型</typeparam>
/// <typeparam name="TAttachment">附件数据类型</typeparam>
/// <typeparam name="TKey">主键类型</typeparam>
public interface IDataAttachmentService<TDbContext, TEntitySet, TAttachment, TKey>
    where TDbContext : DbContext
    where TEntitySet : class, IEntitySet<TKey>
    where TAttachment : class, IAttachment<TKey>
    where TKey : IConvertible
{
    /// <summary>
    /// 新增附件
    /// </summary>
    /// <param name="entitySet">业务数据</param>
    /// <param name="attachments">附件集合</param>
    /// <param name="businessType">业务类型</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task AddAttachmentsAsync(TEntitySet entitySet, IEnumerable<TAttachment>? attachments = default, string? businessType = default);
    /// <summary>
    /// 修改附件, 保留旧附件, 新增新附件, 返回待删除文件列表
    /// </summary>
    /// <param name="entitySet">业务数据</param>
    /// <param name="attachments">附件集合</param>
    /// <param name="businessType">业务类型</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task<IEnumerable<string>?> UpdateAttachmentsAsync(TEntitySet entitySet, IEnumerable<TAttachment>? attachments = default, string? businessType = default, bool isLogical = false);
    /// <summary>
    /// 自动删除附件, 返回待删除文件列表, 适用于实体对象模型从数据库删除时查找原始附件并自动删除
    /// </summary>
    /// <param name="id">业务数据主键</param>
    /// <param name="businessType">业务类型</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns>待删除文件列表, 请在数据库事物提交成功后删除列表中的文件</returns>
    Task<IEnumerable<string>?> DeleteAttachmentsAsync(TKey id, string? businessType = null, bool isLogical = false);
    /// <summary>
    /// 按文件列表删除附件
    /// </summary>
    /// <param name="fileNames">待删除的文件名</param>
    /// <param name="isLogical">是否逻辑操作, 默认不是</param>
    /// <returns></returns>
    Task<IEnumerable<string>?> DeleteAttachmentsAsync(IEnumerable<string> fileNames, bool isLogical = false);
}

/// <summary>
/// 业务数据附件类服务
/// 字符串作为主键的默认实现
/// 一个业务数据中仅有一个类型为: Attachment 的业务数据的附件集合, 根据 BusinessType 字段区分用途
/// </summary>
/// <typeparam name="TDbContext">数据库上下文</typeparam>
/// <typeparam name="TEntitySet">业务数据类型</typeparam>
public interface IDataAttachmentService<TDbContext, TEntitySet> :
    IDataAttachmentService<TDbContext, TEntitySet, Attachment, string>
    where TDbContext : DbContext
    where TEntitySet : class, IEntitySet
{ }